package org.batatasframework.support.database.sql.where;

import java.util.List;

import org.batatasframework.support.database.LogicSymbol;
import org.batatasframework.support.database.metadatas.FieldMetadata;
import org.batatasframework.support.database.sql.QueryParameter;
import org.batatasframework.support.database.sql.TableInstance;

import cn.bonoon.kernel.util.Opt;

public class DefaultQueryFragment extends AbstractQueryFragment<Object>{

	/**
	 * <pre>
	 * 表示当{@link #value}=null时，是否添加 field is null的查询条件 
	 * 
	 * 默认情况下如果{@link #value}=null，则不会添加任何的查询条件
	 * </pre>
	 */
	private boolean ignoreNull = true;

	private final ZeroQueryFragment zeroQueryFragment;
	
	public DefaultQueryFragment(TableInstance tableSource, FieldMetadata fieldMetadata, Opt opt, Object value, ZeroQueryFragment zeroQueryFragment) {
		super(tableSource, fieldMetadata, opt, value);
		
		this.zeroQueryFragment = zeroQueryFragment;
	}
	
	@Override
	public void parse(LogicSymbol logic, StringBuilder sql, List<QueryParameter> paramenters) throws Exception {

		if(null == value){
			if(!ignoreNull){
				//sql.append(logic.getValue()).append(columnName).append(Opt.NULL.getSimpleOperator());
				zeroQueryFragment.reset(Opt.NULL);
				zeroQueryFragment.parse(logic, sql, paramenters);
			}
			
			/*
			 * 当查询的参数为null时，查询条件的"ignoreNull"属性表示是否使用空查询，
			 * 即自动添加 "x.field is null"的查询条件
			 */
			return;
		}

		Opt opt = this.opt;
		
		if(opt.getValueCount() == 0){
			//sql.append(logic.getValue()).append(columnName).append(opt.getOperator());
			zeroQueryFragment.parse(logic, sql, paramenters);
		}else{
			if(addParamenter(paramenters, value)){
				sql.append(logic.getValue());
				if(opt == Opt.NE || opt == Opt.NI){
					sql.append('(').append(columnName)
						.append(" is null or ").append(columnName)
						.append(Opt.NE.getOperator()).append(')');
					
					/*
					 * 不等于某个值，需要把null的情况处理一下，如：a<>10，理论上应该把所有非10的查出来
					 * 可以在实际查询的时间，那些a=null的是没有被查出来的
					 */
				}else{
					if(opt == Opt.IN) opt = Opt.EQ;
					sql.append(columnName).append(opt.getOperator());
				}
			}
		}
	}
}
